#!/usr/local/python/bin/python
# coding=utf-8
__author__ = 'Junjie.M'

from  tools.Util import Util


class ImpalaTypeUtil:
    _types = ['BIGINT', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'REAL', 'SMALLINT']
    _types.extend(['TINYINT', 'BOOLEAN', 'CHAR', 'STRING', 'VARCHAR', 'TIMESTAMP'])

    # 检查字段类型
    def checkType(self, str, impalaType):
        if impalaType not in self._types:
            return False

        if 'BIGINT' == impalaType:
            return self.isBigInt(str)

        if 'DECIMAL' == impalaType:
            return self.isDecimal(str)

        if 'DOUBLE' == impalaType:
            return self.isDouble(str)

        if 'FLOAT' == impalaType:
            return self.isFloat(str)

        if 'INT' == impalaType:
            return self.isInt(str)

        if 'REAL' == impalaType:
            return self.isReal(str)

        if 'SMALLINT' == impalaType:
            return self.isSmallInt(str)

        if 'TINYINT' == impalaType:
            return self.isTinyInt(str)

        return True

    def isBigInt(self, str):
        try:
            x = long(str)
            return x >= -(2 ** 63) and x <= (2 ** 63) - 1
        except Exception:
            return False

    def isDecimal(self, str):
        try:
            x = float(str)
            return True
        except Exception:
            return False

    def isDouble(self, str):
        try:
            x = float(str)
            return True
        except Exception:
            return False

    def isFloat(self, str):
        try:
            x = float(str)
            return True
        except Exception:
            return False

    def isInt(self, str):
        try:
            x = int(str)
            return x >= -(2 ** 31) and x <= (2 ** 31) - 1
        except Exception:
            return False

    def isReal(self, str):
        try:
            x = float(str)
            return True
        except Exception:
            return False

    def isSmallInt(self, str):
        try:
            x = int(str)
            return x >= -(2 ** 16) and x <= (2 ** 16) - 1
        except Exception:
            return False

    def isTinyInt(self, str):
        try:
            x = int(str)
            return x >= -(2 ** 7) and x <= 2 ** 7 - 1
        except Exception:
            return False

    # 验证是否是合法数字
    @staticmethod
    def checkDecimal(str, intLen, digitLen):
        if digitLen > intLen:
            return False

        # 为空时无法判断，故方行
        if Util.isEmpty(str):
            return True

        # 判断是否是数字或小数
        if not ImpalaTypeUtil().isDecimal(str):
            return False

        intVal = str
        digitVal = ''
        if ( '.' in str):
            if str.count(r'.') > 1:
                return False
            # 含有小数
            vals = str.split(r'.')
            intVal = vals[0]
            digitVal = vals[1]

        # 超过整数限制
        if len(intVal) > (intLen - digitLen):
            return False

        if len(digitVal) > digitLen:
            return False

        return True



